        TITL DAI FIRMWARE C1FB-C436  V1.1
        ORG   :C1FB
*
*
*
*********************************************
* DECREMENT FLOATING POINT NUMBER IN MEMORY *
*********************************************
*
* Routine is not used.
*
* If the number is 0, or the exponent < 0, -1 is
* added to the mantissa. Else, a -1 is added/
* subtracted to/from the least significant '1' of
* the mantissa.
* If the lsb of the mantissa is already a rounded
* value, no decrement occurs.
*
* Entry: HL points to FPT number in M.
* Exit:  All registers preserved.
*
FDCM    PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        LXI   D,:C21A   Addr. FPT(-1)
        MOV   A,M       Get exp.byte
        ANI   :7F       Mask sign bit
        JZ    :C1AC     If nr=0: add -1, abort
        CPI   :40       Is exp. negative ?
        JNC   :C1AC     Then add -1, abort
        CPI   :18       Max. nr of mantissa bits
        JNC   :C14D     Abort if lsb mantissa is
 REM not lsb of number
        CMP   M         Check if nr. is negative
        INX   H
        JZ    :C152     Into FINM for neg. nr
        JMP   :C10F     Idem for pos. nr.
*
* DATA - (not used):
*
FPM1    DATA  :81       FPT (-1)
        DATA  :80
        DATA  :00
        DATA  :00
*
**********************
* SAVE MACC ON STACK *
**********************
*
* Contents MACC is placed on TOS. Returnaddress
* is saved.
*
* Entry: None.
* Exit:  All registers preserved.
*        On stack: HL; returnaddress; MACC.
*
PUSH    SHLD  :00E1     Save HL
        XTHL            Get returnaddress
        SHLD  :00DF     Save it
        PUSH  H         and put it on stack again
        LXI   H,:0000
        DAD   SP        SP in HL
        RST   4         Copy MACC to TOS
        DATA  :0F
        LHLD  :00DF     Get returnaddr.
        PUSH  H         on stack
LC52    LHLD  :00E1     Get original HL
        RET
*
****************************
* RETRIEVE MACC FROM STACK *
****************************
*
* Gets data from TOS and place it in MACC.
*
* Entry: None.
* Exit:  All registers preserved.
*
POP     SHLD  :00E1     Save HL
        POP   H         Get returnaddress
        SHLD  :00DF     Save it
        LXI   H,:0000
        DAD   SP        Get SP in HL
        RST   4         Copy TOS to MACC
        DATA  :0C
        POP   H
        LHLD  :00DF     Get returnaddress
        XTHL            on stack
        JMP   :C230     Restore HL, ret
*
*****************************************
* INPUT A FLOATING POINT NUMBER TO MACC *
*****************************************
*
* Converts a FPT number to binary into MACC.
* The input string is converted as a integer FPT
* number, then multiplied/divided by a power of
* 10, corresponding to the explicit exponent and
* placement of the decimal point.
*
* Entry: C points to 1st digit of FPT nr in input.
* Exit:  CY=1: No error.
*        CY=0: Over/underflow error.
*        C points past FPT string in input.
*        ABDEHL, rest of F preserved.
*
FCB     STC             CY=1
        PUSH  PSW
        PUSH  D
        PUSH  H
        CALL  :C2AE     Clear MACC+DEH; L=2B
LC53    CALL  :C32F     Get bin.value of input char
        CC    :C2BA     Value found: Move digit into
 REM MACC
        JC    :C250     and get next digit
        CPI   :2E       '.' ?
        JZ    :C26B     Then jump
        DCR   E
        INR   E
        JZ    :C2A6     If error
        CPI   :45       'E' ?
        JZ    :C284     Then jump
        JMP   :C29F     Convert FPT exp; quit
 REM
* If digit is '.':
 REM
LC54    CALL  :C2D5     E=0, H=H+1
LC55    CALL  :C32F     Get bin.value of input char
        CC    :C2BA     If found: Move digit into
 REM MACC
        JC    :C26E     and get next digit
        DCR   E
        INR   E
        JZ    :C2A6     If error
        CPI   :45       'E' ?
        CNZ   :C2D9     H=0 if not
        JNZ   :C29F     If not: convert exp, quit
 REM
* If digit is 'E':
 REM
LC56    CALL  :C2D9     H=0
        CALL  :C32F     Get bin.value of input char
        CZ    :C2DC     If '+' or '-': char in L
        CZ    :C32F     Then get bin.value of next
 REM char
        JNC   :C2A6     Error if no char found
        CALL  :C2DE     H = 10 * H + A
        CALL  :C32F     Get bin.value of input char
        CC    :C2DE     If found: H = 10 * H + A
        CC    :C32F     Get bin.value of input char
 REM
* If digit is number:
 REM
LC57    CALL  :C2EB     Convert FPT exponent
LC58    POP   H
        POP   D
        POP   PSW       CY=1
        RET
 REM
* If error:
 REM
LC59    CALL  :C32D     DCR C
LC60    POP   H
        POP   D
        POP   PSW
        CMC             CY=0
        RET
*
* CLEAR MACC AND REGISTERS D, E AND H:
*
* Exit: ABC preserved.
*       L = 2B ('+')
*
LC61    LXI   H,:C45E   Addr. FPT(0)
        RST   4         Copy FPT(0) to MACC
        DATA  :0C
        LXI   D,:0000   Clear DE
        LXI   H,:002B   Clear H, L='+'
        RET
*
* MOVE A DIGIT INTO THE MACC:
*
* MACC = MACC * 10 + A.
*
* Entry: A: Digit 1 - 9.
* Exit:  AFBCHL preserved.
*        D=D-H; E=E-1.
*
LC62    PUSH  PSW
        PUSH  H
        LXI   H,:C34D   Addr FPT (10)
        RST   4         MACC = MACC * 10 (FPT)
        DATA  :06
        PUSH  D
        ADD   A         )
        ADD   A         ) DE = 4 * A
        MOV   E,A       ) (calc offset to startaddr)
        MVI   D,:00     )
        LXI   H,:C45E   Addr table FPT(1-9)
        DAD   D         Calc. addr nr to be added
        POP   D
        RST   4         MACC = MACC + (1-9) (FPT)
        DATA  :00
        POP   H
        MOV   A,D
        SUB   H
        MOV   D,A       D=D-H
        DCR   E         E=E-1
        POP   PSW
        RET
*
LC63    MVI   E,:00
        INR   H
        RET
*
LC64    MVI   H,:00
        RET
*
LC65    MOV   L,A
        RET
*
* H = 10 x H + A:
*
* Exit: AFBCDEL preserved.
*
LC66    PUSH  PSW
        MOV   A,H       A=H
        ADD   A         A=2*H
        ADD   A         A=4*H
        ADD   H         A=5*H
        ADD   A         A=10*H
        MOV   H,A
        POP   PSW
        PUSH  PSW
        ADD   H         A=10*H+A
        MOV   H,A
        POP   PSW
        RET
*
* CONVERT A FPT EXPONENT:
*
* The MACC is multiplied/divided by a power of 10
* corresponding to the 'E'-exponent minus the number
* of digits after the decimal point.
*
* Entry: C:    Points beyond 1st nonuseable char of
*              FPT number in input.
*        L:    Contains sign of exponent.
*        H:    Contains 'E....' exponent (10).
*        MACC: Contains FPT conversion of string of
*              digits.
*        D:    Contains nr of digits after '.'.
* Exit:  BE preserved, AHL corrupted.
*        C:    Decremented to after FPT nr in input.
*        D:    Contains effective exponent.
*
LC67    CALL  :C32D     Decr C
        MOV   A,L       Get exp. sign
        CPI   :2D       '-' ?
        MOV   A,H       Get exponent
        JNZ   :C2F7     If exp. positive
        CMA             ) Else: make exponent
        INR   A         ) positive
LC68    ADD   D         Add nr of digits after '.'
        MOV   D,A       Save result
        JP    :C2FE     If result positive
        CMA             ) Else: make it
        INR   A         ) positive
LC69    PUSH  B
        MVI   B,:05     Nr of times of multipl.
        LXI   H,:C34D   Addr table powers of 10
LC70    ORA   A         Flags on result LC68
        RAR             lsb in carry
        JNC   :C317     If bit=0
        PUSH  PSW
        MOV   A,D       Check if multipl/div
        ORA   A
        JM    :C311     If division
        RST   4         MACC = MACC * power of 10
        DATA  :06
LC71    JP    :C316     If multiplication
        RST   4         MACC = MACC / power of 10
        DATA  :09
LC72    POP   PSW       Restore A
LC73    INX   H
        INX   H
        INX   H
        INX   H         HL pnts to next ^10
        DCR   B
        JNZ   :C304     Again if not ready
        ORA   A
        JZ    :C32B     If result OK
 REM
* If error:
 REM
        MOV   A,D
        ORA   A         Set flags for error type
        CP    :C04B     If overflow error
        CM    :C065     If underflow error
LC74    POP   B         Normal return
        RET
*
LC75    DCR   C
        RET
*
* GET BINARY VALUE OF INPUT CHARACTER IN A:
*
* Entry: C points to character in input.
* Exit:  C points to next character.
*        BDEHL preserved.
*        CY=1, Z=0: Value in A.
*        CY=0, Z=1: Char is +/-.
*        CY=0, Z=0: otherwise.
*
LC76    CALL  :C073     Get char from line
        INR   C         Update pointer
        CPI   :2B
        RZ              Abort if '+'
        CPI   :2D
        RZ              Abort if '-'
        CPI   :30
        CMC
        RNC             Abort if < #30
        CPI   :3A
        JNC   :C34B     Abort if > #3A
        SUI   :30       Convert ASCII to binary
        PUSH  D
        MOV   D,A
        INR   A         Set Z-flag correctly for
 REM reqd output
        MOV   A,D
        POP   D
        STC             CY=1: value in A
        RET
LC77    ORA   A         Set flags correctly
        RET
*
**************************
* TABLE FPT POWERS OF 10 *
**************************
*
LC233   DATA  :04       FPT 10^1
        DATA  :A0
        DATA  :00
        DATA  :00
*
        DATA  :07       FPT 10^2
        DATA  :C8
        DATA  :00
        DATA  :00
*
        DATA  :0E       FPT 10^4
        DATA  :9C
        DATA  :40
        DATA  :00
*
        DATA  :1B       FPT 10^8
        DATA  :BE
        DATA  :BC
        DATA  :20
*
        DATA  :36       FPT 10^16
        DATA  :8E
        DATA  :1B
        DATA  :CA
*
**********************************************
* CONVERT A FLOATING POINT NUMBER FOR OUTPUT *
**********************************************
*
* A FPT number in MACC is converted to ASCII in
* outputbuffer 00E4-F1. The sign is in 00E4, the
* decimal point in 00E5. The normalized value of
* the mantissa is in 00E6-EC (7 digits). In 00F1
* is the 10's exponent in 2-complement binairy
* signed format.
*
* Exit: A=6 (number of significant digits).
*       BCDEHL, MACC preserved.
*
FBC     PUSH  B
        PUSH  D
        PUSH  H
        CALL  :C21E     Save MACC on stack
        RST   4         Copy MACC to reg A,B,C,D
        DATA  :15
        PUSH  PSW       Save exp.byte
        ORA   B
        ORA   C
        ORA   D
        JZ    :C3D4     If FPT nr is zero
        POP   PSW       Get exp.byte
        PUSH  PSW
        MVI   H,:00
        ANI   :7F       Mask sign bit mantissa
        CPI   :40
        JC    :C380     If exp is positive
        DCR   H
        CMA             ) Else: convert
        ANI   :7F       ) exponent to
        INR   A         ) positive
LC78    PUSH  PSW       Save value exponent
        XRA   A
        RST   4         Copy mantissa to MACC
        DATA  :12
        POP   PSW       Get exp.value
        MOV   B,H       B=FF (exp.<0), 00 (exp.>0)
        LXI   H,:C437   Addr table powers FPT(2)
        MVI   C,:00
        MVI   D,:07     7 digits to be examined
LC79    RRC             Shift exp. into carry
        PUSH  PSW       Save rest of exp.
        MOV   A,M       Get 10's power byte
        INX   H         Points to next
        JNC   :C3A2     If n-th power of 2=0:
 REM go to next
        ADD   C
        MOV   C,A       Total 10's power in C
        DCR   B
        INR   B
        JNZ   :C39D     Jump if exp. negative
        RST   4         Multipl. mantissa by
        DATA  :06       (2^2^n)/10^m
LC80    JZ    :C3A2
        RST   4         Divide mantissa by
        DATA  :09       (2^2^n)/10^m
LC81    INX   H
        INX   H
        INX   H
        INX   H         Pnts to next in table
        POP   PSW       Get rest exponent
        DCR   D         Decr digit count
        JNZ   :C38D     Again if not 7 digits done
        DCR   B
        INR   B
        LXI   H,:C45A   Addr FPT (0.1)
        JNZ   :C3C4     If exp. negative
 REM
* If exponent positive:
 REM
LC82    PUSH  H
        LXI   H,:C462   Addr FPT(1)
        CALL  :C079     Compare with 1
        POP   H
        JM    :C3D4     Jump if normalized
        RST   4         MACC = MACC * 0.1 (FPT)
        DATA  :06
        INR   C         Update 10's power
        JMP   :C3B3     Cont. normalisation
 REM
* If exponent negative:
 REM
LC83    MOV   A,C       )
        CMA             ) Change 10's power
        INR   A         ) to neg. value
        MOV   C,A       )
LC84    CALL  :C079     Compare with 0,1
        JP    :C3D4     Jump if normalized
        RST   4         MACC = MACC / 0.1 (FPT)
        DATA  :09
        DCR   C         Update 10's power
        JMP   :C3C8     Cont. normalisation
 REM
* Load output buffer:
 REM
LC85    MOV   A,C       Get 10's power
        STA   :00F1     In output buffer
        POP   PSW       Get signbyte mantissa
        ORA   A         Set flags on it
        LXI   H,:00E4   Addr output buffer
        MVI   M,:2B     '+' in buffer
        JP    :C3E4     If mantissa is positive
        MVI   M,:2D     Else: '-' in buffer
LC86    INX   H
        MVI   M,:2E     '.' in 00E5
        INX   H
        PUSH  H
        RST   4         Copy MACC to reg A,B,C,D
        DATA  :15
        PUSH  PSW       Save exp.byte
        XRA   A
        RST   4         Copy mantissa to MACC
        DATA  :12
        POP   PSW       Get exp.byte
        CMA             )
        INR   A         ) 2-compl.
        ANI   :7F       Mask sign bit mantissa
        LXI   H,:C610   Addr INT(10)
        RST   4         MACC = MACC * 10 (INT)
        DATA  :54
        LXI   H,:C420   Addr. INT(1)
        DCR   A
        JM    :C402     If exp. converted
        RST   4         Shift MACC right
        DATA  :72
LC88    JP    :C3FC     If not ready
        POP   H
        RST   4         Copy MACC to reg A,B,C,D
        DATA  :15
        ADI   :30       Exp.byte in ASCII
        MOV   M,A       Into outputbuffer
        INX   H
        MVI   B,:06     6 sign. digits for mantissa
LC89    CALL  :C424     Convert one digit to ASCII
        MOV   M,A       Into output buffer
        INX   H
        DCR   B
        JNZ   :C40E     Next digit if not ready
        CALL  :C234     Retrieve MACC from TOS
        POP   H
        POP   D
        POP   B
        MVI   A,:06     6 sign. digits in outputbuf
        RET
*
* DATA:
*
I1      DATA  :00       INT (1)
        DATA  :00
        DATA  :00
        DATA  :01
*
* CONVERT A DIGIT FOR OUTPUT:
*
* Highest byte of MACC *10 is made ASCII.
*
* Exit: A: Converted highest byte MACC.
*       BCHL preserved. DE corrupted.
*
LC90    PUSH  B
        PUSH  H
        RST   4         Copy MACC to reg A,B,C,D
        DATA  :15
        XRA   A         Clear highest byte
        RST   4         Copy reg A,B,C,D to MACC
        DATA  :12
        LXI   H,:C610   Addr INT(10)
        RST   4         MACC = MACC * 10 (INT)
        DATA  :54
        RST   4         Copy MACC to reg A,B,C,D
        DATA  :15
        ADI   :30       Make highest byte ASCII
        POP   H
        POP   B
        RET
*
*
*
        END
